<script setup lang="ts">
import { ref, onMounted } from "vue";
import DeviceCard from "./components/DeviceCard.vue";
import { ElMessageBox } from "element-plus";
import { HttpClient } from "@/utils/http-client";
import { UserFriendlyException } from "@/exceptions/IUserFriendlyException";
import { Task } from "@/utils/task";
import type { ProductionBaseResponse } from "./types/production-base-response";
import type { ProductionWorkshopResponse } from "./types/production-workshop-response";
import type { DeviceHostResponse } from "./types/device-host-response";
import type { ProductionProcessResponse } from "./types/production-process-response";
import type { DeviceMaintenanceResponse } from "./types/device-maintenance-response";
import type { DevicePartResponse } from "./types/device-part-response";
import { useDeviceHomeStore } from "./device-home/device-home-store";
import { storeToRefs } from "pinia";
import { String } from "@/utils/string";
import { useRoute } from "vue-router";

interface DeviceInfo {
  deviceId: string;
  resourceId: string;
  mixingPercentage: number;
  dispersionPercentage: number;
  mixingStatus: string;
  dispersionStatus: string;
}

const baseUrl = import.meta.env.VITE_DEVICE_OPS_SERVICE_BASE_URL;

const httpClient = new HttpClient();
const deviceInfoList = ref<DeviceInfo[]>([]);
const siteList = ref<ProductionBaseResponse[]>([]);
const isLoading = ref(false);
const workshopList = ref<ProductionWorkshopResponse[]>([]);
const productionProcessList = ref<ProductionProcessResponse[]>([]);
const deviceHostList = ref<DeviceHostResponse[]>([]);
const deviceMaintenanceList = ref<DeviceMaintenanceResponse[]>([]);
const deviceHomeStore = useDeviceHomeStore();

const { site, workshopId, productionProcessId, deviceHostId } = storeToRefs(deviceHomeStore);
const route = useRoute();

onMounted(async () => {
  isLoading.value = true;
  try {
    await Task.waitAsync(200);
    const deviceHostId = route.query.deviceHostId as string;

    if (!String.isNullOrWhitespace(deviceHostId)) {
      onLoadByDeviceHostAsync(deviceHostId);
    } else {
      const list = await httpClient.getAsync<ProductionBaseResponse[]>(
        baseUrl + "/production-bases"
      );
      siteList.value = list;
      await onLoadAsync();
    }
  } catch (err) {
    if (err instanceof UserFriendlyException) {
      console.info(err);
      ElMessageBox.alert(err.message, "错误提示");
    } else {
      console.error(err);
      ElMessageBox.alert("更新基地列表错误！", "错误提示");
    }
  } finally {
    isLoading.value = false;
  }
});

async function onLoadAsync() {
  if (site.value !== undefined) {
    await onSiteChangedAsync(site.value);

    if (!String.isNullOrWhitespace(workshopId.value)) {
      await onWorkshopChangedAsync(workshopId.value);

      if (!String.isNullOrWhitespace(productionProcessId.value)) {
        await onProcessChangedAsync(productionProcessId.value);

        if (!String.isNullOrWhitespace(deviceHostId.value)) {
          await onDeviceHostChangedAsync(deviceHostId.value);
        }
      }
    }
  }
}

async function onLoadByDeviceHostAsync(id: string) {
  deviceHostId.value = id;
  await onDeviceHostChangedAsync(deviceHostId.value);
  const deviceHost = await httpClient.getAsync<DeviceHostResponse>(baseUrl + "/device-hosts/" + id);
  const process = await httpClient.getAsync<ProductionProcessResponse>(
    baseUrl + "/production-processes/" + deviceHost.productionProcessId
  );
  productionProcessId.value = process.id;
  const workshop = await httpClient.getAsync<ProductionWorkshopResponse>(
    baseUrl + "/production-workshops/" + process.productionWorkshopId
  );
  workshopId.value = workshop.id;
  const base = await httpClient.getAsync<ProductionBaseResponse>(
    baseUrl + "/production-bases/" + workshop.siteId
  );
  site.value = base.id;

  await onLoadAsync();
}

async function onSiteChangedAsync(value: number) {
  try {
    isLoading.value = true;
    const list = await httpClient.getAsync<ProductionWorkshopResponse[]>(
      baseUrl + `/production-bases/${value}/production-workshops`
    );
    workshopList.value = list;
  } catch (err) {
    if (err instanceof UserFriendlyException) {
      console.info(err);
      ElMessageBox.alert(err.message, "错误提示");
    } else {
      console.error(err);
      ElMessageBox.alert("更新车间名称列表错误！", "错误提示");
    }
  } finally {
    isLoading.value = false;
  }
}

const onSiteChanged = async (value: number) => {
  onSiteChangedAsync(value);
};

async function onWorkshopChangedAsync(value: string) {
  try {
    isLoading.value = true;
    const list = await httpClient.getAsync<ProductionProcessResponse[]>(
      baseUrl + `/production-workshops/${value}/production-processes`
    );
    productionProcessList.value = list;
  } catch (err) {
    if (err instanceof UserFriendlyException) {
      console.info(err);
      ElMessageBox.alert(err.message, "错误提示");
    } else {
      console.error(err);
      ElMessageBox.alert("更新工序名称列表错误！", "错误提示");
    }
  } finally {
    isLoading.value = false;
  }
}

const onWorkshopChanged = async (value: string) => {
  await onWorkshopChangedAsync(value);
};

async function onProcessChangedAsync(value: string) {
  try {
    isLoading.value = true;
    const list = await httpClient.getAsync<DeviceHostResponse[]>(
      baseUrl + `/production-processes/${value}/device-hosts`
    );
    deviceHostList.value = list;
  } catch (err) {
    if (err instanceof UserFriendlyException) {
      console.info(err);
      ElMessageBox.alert(err.message, "错误提示");
    } else {
      console.error(err);
      ElMessageBox.alert("更新设备列表错误！", "错误提示");
    }
  } finally {
    isLoading.value = false;
  }
}

const onProcessChanged = async (value: string) => {
  await onProcessChangedAsync(value);
};

async function onDeviceHostChangedAsync(value: string) {
  isLoading.value = true;
  try {
    const list = await httpClient.getAsync<DeviceMaintenanceResponse[]>(
      baseUrl + "/device-hosts/" + value + "/device-maintenances"
    );
    deviceMaintenanceList.value = list;
    updateDeviceInfosAsync();
  } catch (err) {
    if (err instanceof UserFriendlyException) {
      console.info(err);
      ElMessageBox.alert(err.message, "错误提示");
    } else {
      console.error(err);
      ElMessageBox.alert("更新设备维护列表错误！", "错误提示");
    }
  } finally {
    isLoading.value = false;
  }
}

const onDeviceHostChanged = async (value: string) => {
  await onDeviceHostChangedAsync(value);
};

async function getDevicePartsAsync(deviceMaintenanceId: string) {
  const parts = await httpClient.getAsync<DevicePartResponse[]>(
    baseUrl + "/device-maintenances/" + deviceMaintenanceId + "/parts"
  );
  return parts;
}

async function updateDeviceInfosAsync() {
  deviceInfoList.value = [];
  deviceMaintenanceList.value.forEach(async (e) => {
    const parts = await getDevicePartsAsync(e.id);
    const mixingPart = parts.find((item) => item.devicePartName === "搅拌轴承");
    const dispersionPart = parts.find((item) => item.devicePartName === "分散轴承");

    deviceInfoList.value.push({
      deviceId: e.id,
      mixingStatus:
        mixingPart == null
          ? "normal"
          : mixingPart.currentLifetime >= mixingPart.accumulatedDowntime
          ? "exception"
          : mixingPart.currentLifetime >= mixingPart.economicLifetimeThreshold
          ? "warning"
          : "normal",
      dispersionStatus:
        dispersionPart == null
          ? "normal"
          : dispersionPart.currentLifetime >= dispersionPart.accumulatedDowntime
          ? "exception"
          : dispersionPart.currentLifetime >= dispersionPart.economicLifetimeThreshold
          ? "warning"
          : "normal",
      resourceId: e.deviceName,
      mixingPercentage:
        mixingPart == null
          ? 0
          : Math.floor((mixingPart.currentLifetime / mixingPart.accumulatedDowntime) * 100),
      dispersionPercentage:
        dispersionPart == null
          ? 0
          : Math.floor((dispersionPart.currentLifetime / dispersionPart.accumulatedDowntime) * 100)
    });
  });
}
</script>

<template>
  <main class="main-container" v-loading="isLoading">
    <div class="header-container">
      <div>
        <el-text style="width: 80px">基地名称：</el-text>
        <el-select style="width: 200px" v-model="site" @change="onSiteChanged">
          <el-option
            v-for="siteItem in siteList"
            :key="siteItem.id"
            :label="siteItem.siteName"
            :value="siteItem.id"
          ></el-option>
        </el-select>
      </div>
      <div>
        <el-text style="width: 80px">车间名称：</el-text>
        <el-select style="width: 200px" v-model="workshopId" @change="onWorkshopChanged">
          <el-option
            v-for="workshop in workshopList"
            :key="workshop.id"
            :label="workshop.workshopName"
            :value="workshop.id"
          ></el-option>
        </el-select>
      </div>
      <div>
        <el-text style="width: 80px">工序名称：</el-text>
        <el-select style="width: 200px" v-model="productionProcessId" @change="onProcessChanged">
          <el-option
            v-for="productionProcess in productionProcessList"
            :key="productionProcess.id"
            :label="productionProcess.processName"
            :value="productionProcess.id"
          ></el-option>
        </el-select>
      </div>
      <div>
        <el-text style="width: 80px">设备主机：</el-text>
        <el-select style="width: 200px" v-model="deviceHostId" @change="onDeviceHostChanged">
          <el-option
            v-for="deviceHost in deviceHostList"
            :key="deviceHost.id"
            :label="deviceHost.deviceHostName"
            :value="deviceHost.id"
          ></el-option>
        </el-select>
      </div>
    </div>
    <div class="device-info-container">
      <DeviceCard
        class="device-info-item"
        v-for="info in deviceInfoList"
        :key="info.resourceId"
        :resource-id="info.resourceId"
        :dispersion-percentage="info.dispersionPercentage"
        :mixing-percentage="info.mixingPercentage"
        :mixing-status="info.mixingStatus"
        :dispersion-status="info.dispersionStatus"
        :device-id="info.deviceId"
      ></DeviceCard>
    </div>
  </main>
</template>

<style lang="scss" scoped>
.main-container {
  padding-right: 8px;
  padding-top: 8px;
  background-color: rgba(241, 236, 236, 0.877);
  min-height: 100%;

  .header-container {
    margin-left: 8px;
    margin-bottom: 8px;
    display: flex;
    align-items: center;

    > div {
      margin-right: 8px;
    }
  }

  .device-info-container {
    display: flex;
    flex-wrap: wrap;
    .device-info-item {
      margin-left: 8px;
      margin-bottom: 8px;
    }
  }
}
</style>